package com.geline.web.enums;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * 参考 https://blog.csdn.net/angerwind/article/details/97000162
 * @author mengxin
 * @date 2025/4/1
 */
@Slf4j
public enum FileTypeExtension {
    bmp("424d228c010000000000,424d8240090000000000,424d8e1b030000000000"),
    png("89504e470d0a1a0a0000"),
    jpeg("ffd8ffe000104a464946"),
    jpg("ffd8ffe000104a464946"),
    gif("47494638396126026f01"),
    mp4("00000020667479706d70"),
    avi("52494646d07d60074156"),
    rmvb("2e524d46000000120001"),
    mid("4d546864000000060001"),
    rar("526172211a0700cf9073"),
    zip("504b0304140000000800"),
    gz("1f8b0800000000000000"),
    jar("504b03040a0000000000"),
    pdf("255044462d312e3"),
    wps("d0cf11e0a1b11ae10000"),
    doc("d0cf11e0a1b11ae10000"),
    docx("504b0304140006000800,504b03040a0000000000"),
    xls("d0cf11e0a1b11ae10000"),
    xlsx("f323c4f1de17cf010004,504b0304140002000800"),
    ppt("d0cf11e0a1b11ae10000"),
    pptx("d0cf11e0a1b11ae10000");

    private String byteHex;

    FileTypeExtension(String byteHex) {
        this.byteHex = byteHex;
    }

    public String getByteHex() {
        return byteHex;
    }

    public static void validateMultipartFile(MultipartFile file) {
        try {
            validateFile(file.getOriginalFilename(), file.getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void validateFile(String fileName, byte[] fileBytes) {
        String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        String hexString = getFileHexString(fileBytes);
        if(contains(extension)){
            FileTypeExtension fileTypeExtension = FileTypeExtension.valueOf(extension);
            String fileTypeHex = fileTypeExtension.getByteHex();
            boolean find = false;
            for(String typeHex : fileTypeHex.split(",")){
                if(hexString.startsWith(typeHex)){
                    find = true;
                    break;
                }
            }
            if(!find){
                log.warn("{} : fileTypeHex={}, hexString={}", fileName, fileTypeHex, hexString.substring(0, 20));
                throw new IllegalArgumentException("非法文件(FILE_BYTE不匹配)！");
            }
        }
    }

    public static boolean contains(String extension) {
        for (FileTypeExtension value : FileTypeExtension.values()) {
            if(value.name().equals(extension)){
                return true;
            }
        }
        return false;
    }

    public static String getFileHexString(byte[] b) {
        StringBuilder stringBuilder = new StringBuilder();
        if(b == null || b.length == 0) {
            return null;
        }
        for (int i = 0; i < b.length; i++) {
            int v = b[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
}
